/**
 * Sample Skeleton for "SalaryDisplayAttendance.fxml" Controller Class
 * You can copy and paste this code into your favorite IDE
 **/

package com.pentofab.payrollmanagement.ui.controller;

import java.io.IOException;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.ResourceBundle;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Modality;
import javafx.stage.Stage;

import com.pentofab.payrollmanagement.application.PayRollApplication;
import com.pentofab.payrollmanagement.application.PayrollApplicationFactory;
import com.pentofab.payrollmanagement.dao.EmployeeDao;
import com.pentofab.payrollmanagement.dao.SalaryDAO;
import com.pentofab.payrollmanagement.dao.model.Company;
import com.pentofab.payrollmanagement.dao.model.Employee;
import com.pentofab.payrollmanagement.dao.model.SalaryAdvance;
import com.pentofab.payrollmanagement.dao.model.SalaryAdvanceDetail;
import com.pentofab.payrollmanagement.dao.model.UserAccounts;
import com.pentofab.payrollmanagement.database.impl.SalaryTableSQLConstants;
import com.pentofab.payrollmanagement.exception.BusinessException;
import com.pentofab.payrollmanagement.ui.control.CustomTextField;
import com.pentofab.payrollmanagement.utilities.PayRollUtility;


public class SalaryAdvanceController extends AbstractUIController implements FormValidator,
Initializable {

	private Company currentcompany;
	private UserAccounts userAcounts;


	@FXML	
	private CustomTextField advance;
	@FXML
	private TextField company;
	@FXML
	private TextField departMent;
	@FXML
	private TextField empId;
	@FXML
	private TextField empName;
	@FXML
	private GridPane root;
	@FXML
	private TableColumn<SalaryAdvanceDetail, String> employeeIdCol;
	@FXML
	private TableColumn<SalaryAdvanceDetail, String> advAmt;
	@FXML
	private CustomTextField recoveryAmount;
	
	@FXML
	private TableColumn<SalaryAdvanceDetail, String> balance;
	@FXML
	private TableView<SalaryAdvanceDetail> tableView;
	@FXML
	Button save;
	@FXML
	Button delete;
	String enteredEmpId = null;
	SalaryDAO salaryDAO = PayrollApplicationFactory.getSalaryDAO();
	private EmployeeDao employeeMgmt = PayrollApplicationFactory.getEmployeeMgmt();
	Employee employee;
	final private ObservableList<SalaryAdvanceDetail> data = FXCollections.observableArrayList();

	public void goBack() {

		enteredEmpId = null;
		if (getParent() != null && getParent().length() > 0) {
			PayrollApplicationFactory.getMainController().showScreen(
					getParent(), false);
		}
	}

	public void reset() {

		enteredEmpId = null;
		refreshUI();
	}

	public void save() {

		try {
			SalaryAdvance salaryAdvance = new SalaryAdvance();
			String validationMSG = getValidationMessage();
			if(!validationMSG.equals("")){
				showError(validationMSG);
				return;
			}

			salaryAdvance.setEmployeeId(employee.getEmpId());
			salaryAdvance.setAdvance(advance.getText());

			salaryDAO.appliForAdvance(salaryAdvance);
			save.setDisable(true);
			showInfo("Successfully applied for Salary advance");
			refreshUI();

		} catch (BusinessException e) {
			showError(e.getMessage());
			return;
		}

	}
	public void delete() {

		try {
			SalaryAdvanceDetail detail = tableView.getSelectionModel().getSelectedItem();

			if (detail == null) {
				showInfo("Please select an entry to delete.");
			}

			if (showConfirmDialog("Plese confirm deletion of selected Advance")) {

				salaryDAO.deleteSalaryAdvance(detail.getEmployeeIdCol(),detail.getRowNum());
			}
			showInfo("Entry deleted successfully");
			refreshUI();
		} catch (BusinessException e) {
			e.printStackTrace();
			showError(e.getMessage());
		}
	}

	@Override
	public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
		textFieldFocusHandler();
		iniTableProps();
	}

	@Override
	public boolean isValid() {
		return false;
	}

	@Override
	public String getValidationMessage() {

		if(employee == null){

			return "please emter Employee ID to select an employee.";
		}
		if(advance.getText().equals("")){
			return "Please enter valid advance amount.";
		}
		return "";
	}

	@Override
	public Parent getView() {
		return root;
	}

	@Override
	public String getTitle() {
		return "Salary Advance";
	}

	@Override
	public void refreshUI(Object... args) {

		delete.setDisable(true);
		save.setDisable(false);
		data.clear();
		if (args != null && args.length > 0) {
			Company company = (Company) args[0];
			this.currentcompany = company;

			if(args.length > 1 && args[1] instanceof UserAccounts){
				userAcounts = (UserAccounts) args[1];
			}
		}
		advance.clear();
		recoveryAmount.clear();
		
		ArrayList<String> yearList = new ArrayList<String>();
		int year1 = PayRollUtility.getYear();
		for (int i = 0; i < 5; i++) {
			yearList.add(year1 + "");
			year1++;
		}
		if(enteredEmpId == null ){
			
			employee = null;
			empId.clear();
			empName.clear();
			company.clear();
			departMent.clear();
		}
		populatSalaryAdvanceTable();
	}

	private void populatSalaryAdvanceTable() {

		String employeeID = empId.getText();
		tableView.getItems().clear();
		try {

			ArrayList<SalaryAdvance> advanceList =  salaryDAO.getSalaryAdvance(employeeID);
			System.out.println("advanceList ; "+advanceList);
			if(advanceList == null){
				return;
			}

			data.addAll(SalaryAdvanceDetail.getSalaryAdvanceDetailLisy(advanceList));
			tableView.setItems(data);

		} catch (BusinessException e) {

			showError(e.getMessage());
		}

	}

	public void textFieldFocusHandler() {

		empId.focusedProperty().addListener(
				new ChangeListener<Boolean>() {
					@Override
					public void changed(ObservableValue<? extends Boolean> ov,
							Boolean lostFocus, Boolean getFocus) {
						PayRollUtility
						.debug("============== eidLableFocusHandler Start========================");
						if (lostFocus) {
							try {
								String employeeId = empId.getText().trim();
								if (!employeeId.equals("")) {
									PayRollUtility.validateEmpId(employeeId);
									employee = employeeMgmt.getEmpById(employeeId);
									empName.setText(employee.getEmpName());
									company.setText(employee.getCompany().getCompanyID());
									departMent.setText(employee.getDepertment().getCode());
									populatSalaryAdvanceTable();
									delete.setDisable(false);
									enteredEmpId = employeeId;
								}
							} catch (Exception exception) {
								showError(exception.getMessage());
								moveFocusToComp(empId);
								refreshUI();
							}
						}
						PayRollUtility
						.debug("============== eidLableFocusHandler END========================");
					}
				});

	}

	private void iniTableProps() {

		tableView.setEditable(true);
		employeeIdCol.setCellValueFactory(new PropertyValueFactory<SalaryAdvanceDetail, String>("employeeIdCol"));
		balance.setCellValueFactory(new PropertyValueFactory<SalaryAdvanceDetail, String>("balance"));
		advAmt.setCellValueFactory(new PropertyValueFactory<SalaryAdvanceDetail, String>("advAmt"));
	}
	public void recoverAdvance(){

		try {
			
			SalaryAdvanceDetail detail = tableView.getSelectionModel().getSelectedItem();
			if (detail == null) {
				showInfo("Please select an entry to make recovery.");
				return;
			}

			int rowNum =detail.getRowNum();
			String recoveredAmount = recoveryAmount.getText().trim();
			if(recoveredAmount.equals("")){
				
				showError("Recovery Amount can not be empty.");
				moveFocusToComp(recoveryAmount);
				return;
			}
			
			double curRcAmount =  Double.valueOf(recoveredAmount);
			double balAmount =  Double.valueOf(detail.getBalance());
			
			if(balAmount < curRcAmount){
				showError("Entered amount for recovery "+curRcAmount+" is greater than balace amount "+balAmount+"\n Provide valid recovery amount");
				recoveryAmount.clear();
				moveFocusToComp(recoveryAmount);
				return;
			}
			
			if(showConfirmDialog(String.format("Would you like to recover %s for employee %s", recoveredAmount,detail.getEmployeeIdCol()))){
				salaryDAO.recoverAmount(detail.getEmployeeIdCol(), rowNum+"", curRcAmount);
				showInfo(String.format("Recovery of amount %s done", recoveredAmount));
				refreshUI();
			}else{
				
				showInfo(String.format("Recovery operation cancelled."));
			}
		} catch (Exception e) {
			e.printStackTrace();
			showError(e.getMessage());
		}

	}

	
	public void showRecoveryDialog(SalaryAdvanceDetail salAdvance) {
		  try {
/*			  FXMLLoader loader = new FXMLLoader();
				loader.load(loader.getClass().getResourceAsStream("/fxml/AdvanceRecovery.fxml"));*/
			  
				PayrollApplicationFactory.getMainController().showScreen("AdvanceRecovery.fxml", true, this.company,userAcounts);

		  } catch (Exception e) {
		    // Exception gets thrown if the fxml file could not be loaded
		    e.printStackTrace();
		  }
		}
}
